/*
 ||Name		||ID			||Description
 ||Map 		||1			||Sub message of type map
 ||S64 		||2			||Signed 64bit integer
 ||Str 		||3			||UTF-8 encoded string
 ||Bin 		||4			||Binary blob
 ||List		||5			||Sub message of type list

 ROOT message
 ||Length	||4 byte integer	||Total length of message (not including this length field itself)
 ||Body		||HTSMSG-Field * N	||Fields in the root body

 HTSMSG-Field
 ||Type		||1 byte integer	||Type of field (see field type IDs above)
 ||Namelength	||1 byte integer	||Length of name of field. If a field is part of a list message this must be 0
 ||Datalength	||4 byte integer	||Length of field data
 ||Name		||N bytes		||Field name, length as specified by Namelength
 ||Data		||N bytes		||Field payload, for details see below

 */

#ifndef HTSMSG_H_
#define HTSMSG_H_

#include "types.h"
#include "fields.h"

#define HTSMSG_FIELD_TYPE8(x)	((uint8)(x&0xff))

typedef enum {
        HTSMSG_FIELD_NONE = 0,
        HTSMSG_FIELD_MAP = 1,
        HTSMSG_FIELD_S64 = 2,
        HTSMSG_FIELD_STR = 3,
        HTSMSG_FIELD_BIN = 4,
        HTSMSG_FIELD_LIST = 5
} HTSMSG_FIELD_TYPE;

typedef struct {
        uint8 type;
        uint8 name_len;
        uint32 data_len;
        char field[];
}  __attribute__ ((__packed__)) HTSMSG_FIELD;

typedef struct {
        uint32 len;
        char fields[];
}  __attribute__ ((__packed__)) HTSMSG_ROOT;

typedef struct {
        HTSMSG_ROOT* root;
        size_t  num_fields;
        HTSMSG_FIELD* fields[];
} HTSMSG;


/*
 * Function declarations
 */
HTSMSG* htsmsgFromBuffer(char* buffer);
void htsmsgFree(HTSMSG* htsmsg);
HTSMSG* htsmsgNewMessage(size_t num_fields);
HTSMSG_FIELD* htsmsgNewField(uint8 type, const char* name, uint32 value_len,
                const void* value);
const char* htsmsgFieldTypeFromCode(uint8 type);
int htsmsgFieldsToBuffer(HTSMSG* msg);

#endif /* HTSMSG_H_ */
